#define NUM_GAMES 5
#define TERMY if(TERMY_FLAG)
#define TERMY_FLAG 0

#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <time.h>
#include "rngs.h"
#include <strings.h>


void shuffle_deck(int *deck);
void buy_action_card(int *deck);
void get_card_name(int* card, char *charry);
void print_game(struct gameState *state);
void print_game_final(struct gameState *state, int game_count, int player_count);
int get_action(struct gameState state);
int get_king_cards(int *k);
int get_purchase(int *k);


int count_coins(struct gameState state);

FILE *out;

int main(int argc, char const *argv[])
{
	srand(time(NULL));
	
	//initialize gamestart variables
	struct gameState state;
	out = fopen("gameResult.out", "w");
	
	char charry[20];
	
	int i;
	int k[10];
	int money = 0;
	
	int game_count;
	int player_count;
	int action_card;
	int buy_card;
	int seed;
	
	
	for(game_count = 0; game_count < NUM_GAMES; game_count++)
	{
		//seed = rand();
		seed = rand();
		
		player_count = rand()%3 + 2;
		get_king_cards(k);
		
		TERMY printf("Begin Game: %d\nPlayer Count: %d\nSeed: %d\n", game_count, player_count, seed);
		
		fprintf(out, "Begin Game: %d\nPlayer Count: %d\nSeed: %d\n", game_count, player_count, seed);	
		
		fprintf(out, "Using Cards: ");
		for (i = 0; i < 10; i++)
		{
			get_card_name(&k[i], charry);
			fprintf(out, "%d %s; ", k[i], charry);
		}
		
		initializeGame(player_count, k, seed, &state);
		fprintf(out, "\nInitialization complete. Beginning game.\n");
		
		
		while(isGameOver(&state) == 0)
		{
			fprintf(out, "\nBEGIN PLAYER %d\n", whoseTurn(&state)+1);
			print_game(&state);
			money = 0;
			money = count_coins(state);
			
			TERMY printf("%d Money money money: %d\n", whoseTurn(&state)+1, money);
			
			//Play action
			//Current specification will only play one action
			//Poor handling of cards with choices, will fix later
			action_card = get_action(state);
			if (action_card != -1)
			{
				
				TERMY printf("Playing: %d\n", action_card);
				fprintf(out, "Playing: %d\n", action_card);
				playCard(action_card, -1, -1, -1, &state); 
			}else
				fprintf(out, "No actions played.\n");
			
			print_game(&state);
			
			
			//Purchase Phase
			buy_card = get_purchase(k);
			
			if(money >= 8)
			{
				TERMY printf("Player %d bought province\n", whoseTurn(&state)+1);
				fprintf(out, "Player %d bought province\n", whoseTurn(&state)+1);
				buyCard(province, &state);
			}
			else if(money >= 5)
			{
				TERMY printf("Purchase ID: %d\n", buy_card);
				//printf("buyCard is broken when purchasing random card. Can't figure out why.\n");
				
				while(buyCard(buy_card, &state) == -1)	//WHY DOES THIS BREAK!?
					buy_card = get_purchase(k);
				
				get_card_name(&buy_card, charry);
				TERMY printf("Player %d bought %s (%d)\n", whoseTurn(&state)+1, charry, buy_card);
				fprintf(out, "Player %d bought %s (%d)\n", whoseTurn(&state)+1, charry, buy_card);
			}
			else if(money >= 3)
			{
				if(buyCard(silver, &state) != -1)
					TERMY printf("Player %d bought silver\n", whoseTurn(&state)+1);
					fprintf(out, "Player %d bought silver\n", whoseTurn(&state)+1);
			}
			
			fprintf(out, "End of Player %d's turn\n", whoseTurn(&state)+1);

			endTurn(&state);
			
		}
		
		fprintf(out, "Game %d complete.\n\n", game_count);
		print_game_final(&state, game_count, player_count);
	}
	
	printf("TESTS PASS\n");
	
	fclose(out);
	return 0;
}

//Get new set of kingdom cards for initialization
int get_king_cards(int *k)
{
	/* cardy[27]
		1: Card is not a kingdom card, or has already been selected
		0: Card is viable choice
	*/
	int cardy[27] = {1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
	int i, thecard = 1;
	
	for(i = 0; i < 10; i++)
	{
		while(cardy[thecard] == 1)
			thecard = rand() % 27;
		
		cardy[thecard] = 1;
		
		k[i] = thecard;
		//fprintf(out, "Kingdom Card[%d]: %d\n", i, thecard);
	}
	return 0;
}

//Returns hand position of random action card in hand
int get_action(struct gameState state)
{
	int i, cnt = 0;
	int action_array[100];
	int cardy;
	
	
	for (i = 0; i < numHandCards(&state); i++)
	{
		cardy = handCard(i, &state);
		if(cardy > 6 && cardy != gardens) //Kingdom cards only; exclude gardens
		{
			//This if discludes cards needing choices; remove this later
			//When choices are properly handled
			if(cardy != feast && cardy != mine && cardy != remodel && cardy != baron && cardy != minion && cardy != steward && cardy != ambassador && cardy != embargo && cardy != salvager)
			{
				//Record action card position in array
				action_array[cnt] = i;
				cnt++;
			}
		}
	}
	
	if(cnt != 0)
	{
		i = rand()%cnt;
		return action_array[i];
	}
	else
		return -1;
}

//Counts coins in hand
int count_coins(struct gameState state)
{
	int i;
	int money = 0;
	
	for (i = 0; i < numHandCards(&state); i++) 
	{
		if (handCard(i, &state) == gold)
			money += 3;
		else if (handCard(i, &state) == silver)
			money += 2;
		else if (handCard(i, &state) == copper)
			money++;
	}
	
	return money;
}

//Returns enum value of card selected for purchase
int get_purchase(int *k)
{

	int i = rand() % 13;
	if(i < 10)
		return k[i];
	else if(i == 10)
		return duchy;
	else if(i == 11)
		return estate;
	else if(i == 12)
		return gold;
	else
		return -1;
}

//Gets name of input card
void get_card_name(int* card, char *charry)
{
	int cardNumber = *card;
	
	//printf("Card %d\n", cardNumber);
	
	switch( cardNumber ) 
    {
		case curse:
			strcpy(charry, "Curse");
		case estate:
			strcpy(charry, "Estate");
		case duchy:
			strcpy(charry, "Duchy");
		case province:
			strcpy(charry, "Province");
		case copper:
			strcpy(charry, "Copper");
		case silver:
			strcpy(charry, "Silver");
		case gold:
			strcpy(charry, "Gold");
		case adventurer:
			strcpy(charry, "Adventurer");
		case council_room:
			strcpy(charry, "Council Room");
		case feast:
			strcpy(charry, "Feast");
		case gardens:
			strcpy(charry, "Gardens");
		case mine:
			strcpy(charry, "Mine");
		case remodel:
			strcpy(charry, "Remodel");
		case smithy:
			strcpy(charry, "Smithy");
		case village:
			strcpy(charry, "Village");
		case baron:
			strcpy(charry, "Baron");
		case great_hall:
			strcpy(charry, "Great Hall");
		case minion:
			strcpy(charry, "Minion");
		case steward:
			strcpy(charry, "Steward");
		case tribute:
			strcpy(charry, "Tribute");
		case ambassador:
			strcpy(charry, "Ambassador");
		case cutpurse:
			strcpy(charry, "Cutpurse");
		case embargo: 
			strcpy(charry, "Embargo");
		case outpost:
			strcpy(charry, "Outpost");
		case salvager:
			strcpy(charry, "Salvager");
		case sea_hag:
			strcpy(charry, "Sea Hag");
		case treasure_map:
			strcpy(charry, "Treasure Map");
		default:
			strcpy(charry, "?Default?");
	}
	
	//printf("Name: %s\n", charry);
	
}

//Prints gamestate info
void print_game(struct gameState *state){
	int i, j;
	int temp;
	char charry[20];

	fprintf(out, "\n====Game State====");
	
	//Hand Data
	for(i = 0; i < state->numPlayers; i++)
	{
		fprintf(out, "\n\n>>> Player %d", i+1);
		
		fprintf(out, "\n>Deck:\n");
		for(j = 0; j < state->deckCount[i]; j++)
		{
			temp = state->deck[i][j];
			get_card_name(&temp, charry);
			fprintf(out, "%d %s; ", temp, charry);
		}
	
		fprintf(out, "\n>Hand:\n");
		for(j = 0; j < state->handCount[i]; j++)
		{
			temp = state->hand[i][j];
			get_card_name(&temp, charry);
			fprintf(out, "%d %s; ", temp, charry);
		}
		
		fprintf(out, "\n>Discard:\n");
		for(j = 0; j < state->discardCount[i]; j++)
		{
			temp = state->discard[i][j];
			get_card_name(&temp, charry);
			fprintf(out, "%d %s; ", temp, charry);
		}
	}



	fprintf(out, "\n==================\n\n");
}

void print_game_final(struct gameState *state, int game_count, int player_count)
{
	int i, j;
	int temp;
	char charry[20];
	
	fprintf(out, "\n++++==Game %d Complete==++++\n", game_count);
	for(i = 0; i < 27; i++)
		fprintf(out, "\nSupply Count for card %d: %d", i, state->supplyCount[i]);
	
	for(i = 0; i < player_count; i++)
	{
		fprintf(out, "\n\n>>> Player %d", i+1);
		fprintf(out, "\n>Score:\n%d", scoreFor(i, state));
		
		fprintf(out, "\n>Deck:\n");
		for(j = 0; j < state->deckCount[i]; j++)
		{
			temp = state->deck[i][j];
			get_card_name(&temp, charry);
			fprintf(out, "%d %s; ", temp, charry);
		}
	
		fprintf(out, "\n>Hand:\n");
		for(j = 0; j < state->handCount[i]; j++)
		{
			temp = state->hand[i][j];
			get_card_name(&temp, charry);
			fprintf(out, "%d %s; ", temp, charry);
		}
		
		fprintf(out, "\n>Discard:\n");
		for(j = 0; j < state->discardCount[i]; j++)
		{
			temp = state->discard[i][j];
			get_card_name(&temp, charry);
			fprintf(out, "%d %s; ", temp, charry);
		}
	
	
	}
	

	fprintf(out, "\n++++=====================++++\n\n\n");
}
